package cn.jcby.app.excpt;

import cn.jcby.app.excpt.enums.ExceptionMsgEnum;
import cn.jcby.app.lebu.utils.Constants;
import cn.jcby.app.lebu.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.stereotype.Component;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.lang.reflect.UndeclaredThrowableException;

/**
 * @author: lihaotian
 * @since: 2023/12/7 23:33
 * @description
 **/
@RestControllerAdvice
@Component
@Slf4j
public class GlobalException {
    private MessageSource messageSource;
    /**
     * 捕获全局异常类
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Result handle(MethodArgumentNotValidException e) {
        if (e.getBindingResult().hasErrors()) {
            String msg = ((ObjectError) e.getBindingResult().getAllErrors().get(0)).getDefaultMessage();
            return Result.error(ExceptionMsgEnum.ILLEGAL_ARGUMENT.getCode(), this.getI18nMsg(msg));
        } else {
            log.info(e.getMessage(), e);
            return Result.error(ExceptionMsgEnum.ILLEGAL_ARGUMENT.getCode(), this.getI18nMsg(ExceptionMsgEnum.ILLEGAL_ARGUMENT.getMsg()));
        }
    }


    /**
     * 捕获API调用接口的异常类
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MSException.class)
    public Result abstractApiException(MSException e) {
        return Result.error(e.getCode(), e.getMsg());
    }

    /**
     * 前端传入的参数和后端传入的参数接收不匹配
     *
     * @param e
     * @return
     */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public Result handle(HttpMessageNotReadableException e) {
        log.warn(e.getMessage(), e);
        return Result.error(ExceptionMsgEnum.ILLEGAL_ARGUMENT_FORMAT.getCode(), this.getI18nMsg(ExceptionMsgEnum.ILLEGAL_ARGUMENT_FORMAT.getMsg()));
    }

    /**
     * 子类异常(相当于子类不能抛出比父类更广泛异常)
     *
     * @param e
     * @return
     */
    @ExceptionHandler({UndeclaredThrowableException.class})
    public Result handle(UndeclaredThrowableException e) {
        log.warn(e.getMessage(), e);
        return Result.error(ExceptionMsgEnum.INVOKE_IS_REJECT.getCode(), this.getI18nMsg(ExceptionMsgEnum.INVOKE_IS_REJECT.getMsg()));
    }

    /**
     * 异常捕获
     *
     * @param e 捕获的异常，封装返回的对象
     * @return
     */
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e) {
        log.warn(e.getMessage(), e);
        //StringJoiner joiner = new StringJoiner(",");
        //joiner.add(this.getI18nMsg(ExceptionMsgEnum.SYSTEM_EXCEPTION.getMsg())).add(e.getMessage());
        String codeOrMsg = e.getMessage();
        if(Constants.isNumeric(codeOrMsg)){
            return Result.error(Integer.valueOf(codeOrMsg), ExceptionMsgEnum.getMsg(Integer.valueOf(codeOrMsg)));
        }else{
            return Result.error(ExceptionMsgEnum.SYSTEM_EXCEPTION.getCode(), codeOrMsg);
        }

    }

    private String getI18nMsg(String msg) {
        try {
            return this.messageSource.getMessage(msg, (Object[]) null, LocaleContextHolder.getLocale());
        } catch (NoSuchMessageException var3) {
            return msg;
        }
    }

    public GlobalException(MessageSource messageSource) {
        this.messageSource = messageSource;
    }
}
